package thread;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
/**
 * 在这个 before、after注解中，就是一个简单的记时操作，这个操作不是一个线程安全的。
 * 【Spring会在生成代理对象的时候，将成员变量 start，变为一个可以被多个线程访问的共享变量】。
 * 解决：【使用@Around注解，这样就可以将 成员变量start，变为局部变量了】。
 */
public class SpringThreadSafe {

    private long start = 0l;

    @Before(value = "")
    public void before(){
        start = System.currentTimeMillis();
    }

    @After(value = "")
    public void after(){
        long end = System.currentTimeMillis();
        System.out.println(end-start);
    }

    //--------------------------------------------------------------------------------------------
    // 上述写法有线程安全的问题，需要改造一下，这里采用 @Around 注解来解决线程安全的问题。
    //--------------------------------------------------------------------------------------------

    @Around(value = "")
    public void around(ProceedingJoinPoint pjp) throws Throwable {
        long start = System.currentTimeMillis();

        pjp.proceed();

        long end = System.currentTimeMillis();

        System.out.println(end-start);
    }



}
